import { Sprite } from "@/sprites/Sprite.js";
import { motions } from "@/const/motions.js";
import { ImageManager } from "@/managers/ImageManager.js";
import { MotionResolver } from "@/utils/MotionResolver.js";
import { config } from "@/managers/ConfigManager.js";

export class Sprite_SideView extends Sprite {
    static motion_speed = 12;
    constructor() {
        super();
        this.anchor.set(0.5,1);

        this.battler = null;

        this.motion = null;
        this.frameIndex = 0;

        this.waitCount = config.animationSpeed;
        this.cwidth = 0;
        this.cheight = 0;
        this.visible = false;
    }

    setBattler(battler) {
        if (battler != this.battler) {
            this.deattachHandler();
            this.battler = battler;
            this.attachHanlder();
            this.setSource(battler);
        }
    }

    attachHanlder() {
        if (this.battler) {
            this.battler.on('motion-changed', (motionType, oldmotion) => {
                this.startMotion(motionType);
            }).on('astate-changed', (actionState, oldAState) => {
                this.startMotion(MotionResolver.resolveAState(actionState));
            }).on('bnamechanged', (battlerName, oldname) => {
                this.setSource(battlerName);
            });
        }
    }

    deattachHandler() {
        if(this.battler){
            this.battler
            .off('motion-changed')
            .off('astate-changed')
            .off('bnamechanged');
        }
    }

    setSource(battler) {
        this.isReady = false;
        let cb = source => {
            this.source = source;
            if(source){
                this.cwidth = source.width / 9;
                this.cheight = source.height / 6;
                if (!this.motion) {
                    this.startMotion('walk');
                }
                this.visible = true;
                this.updateFrame();
            }
        };
        this.visible=false;
        if (battler.isActor()) {
            ImageManager.loadSvActor(battler.battlerName()).then(cb);
        } else if (battler.isEnemy()) {
            ImageManager.loadSvEnemy(battler.battlerName()).then(cb);
        }
    }

    update() {
        super.update();
        if (this.visible && this.motion) {
            if (++this.waitCount >= config.animationSpeed) {
                this.updateFrame();
                this.waitCount = 0;
            }
        }
    }

    updateFrame(){
        let motionIndex = this.motion.index;
        let frameIndex = this.frameIndex < 3 ? this.frameIndex : 1;
        let cy = motionIndex % 6;
        let cx = (motionIndex - cy) / 2 + frameIndex;
        
        this.setFrame(cx * this.cwidth, cy * this.cheight, this.cwidth, this.cheight);

        if (this.motion.loop) {
            this.frameIndex = (this.frameIndex + 1) % 4;
        } else if (this.frameIndex < 2) {
            ++this.frameIndex;
        } else {
            this.startMotion(MotionResolver.resolve(this.battler));
        }
    }

    startMotion(type) {
        this.motion = motions[type];
        this.frameIndex = 0;
        this.waitCount = 0;
    }

    destroy(opts){
        this.deattachHandler();
        super.destroy(opts);
    }
}